Skip to content

ref(project-state): Introduce a dedicated state for 'new allowed'#5998

Open
Dav1dde wants to merge 2 commits into
masterfrom
dav1d/new-allowed
Open

ref(project-state): Introduce a dedicated state for 'new allowed'#5998
Dav1dde wants to merge 2 commits into
masterfrom
dav1d/new-allowed

Conversation

@Dav1dde
Copy link
Copy Markdown
Member

@Dav1dde Dav1dde commented May 13, 2026

Introduces a dedicated state in the ProjectState for Proxy Relays which do not fetch project configs from upstream.

This makes a few implicit decisions explicit and more obvious. This PR is largely without side-effects. The biggest "hidden" change is that enabled() now returns None for the new state, but all usages of enabled() use it to check feature flags, which will always fail even with the previous dummy state.

Also taking suggestions for a better name than DummyAllowed.

@Dav1dde Dav1dde requested a review from a team as a code owner May 13, 2026 14:25
@Dav1dde Dav1dde self-assigned this May 13, 2026
Copy link
Copy Markdown
Contributor

@loewenheim loewenheim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Am I understanding correctly that it would be nicer to send no project config, rather than one with all fields empty/defaulted, but this is left as future work?

//
// To support this, the proxy Relay would have to act as a pure proxy and not fetch
// the project configuration from its own cache.
continue;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to log a warning here?

Copy link
Copy Markdown
Member Author

@Dav1dde Dav1dde May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided against it, because it would log warnings on the "correctly" setup proxy Relay, instead of the incorrectly setup managed Relay.

Meaning someone could generate these warnings from the outside maliciously and they wouldn't be actionable for the user running the proxy Relay.

But maybe I am also overthinking it.

Comment on lines +540 to +550
macro_rules! pop_envelope {
() => {{
relay_log::trace!("EnvelopeBufferService: popping envelope");
// If we arrived here, know that both projects are available, so we pop the envelope.
//
// Available, doesn't necessarily mean enabled/active.
let envelope = buffer.pop().await?;
let envelope = envelope.expect("Element disappeared despite exclusive excess");
Managed::from_envelope(envelope, services.outcome_aggregator.clone())
}};
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this is a macro and not an async closure?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afaik I ran into problems with the closure borrowing parts mutably, but I'll double check.

Comment on lines +571 to +572
// If the own project state is disabled, we want to drop the envelope and early return since
// we can't do much about it.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is an old comment but it sounds unnecessarily hand-wavy.

Suggested change
// If the own project state is disabled, we want to drop the envelope and early return since
// we can't do much about it.
// If the own project state is disabled, we want to drop the envelope.

sampling_project_info,
} => {
let mut envelope = pop_envelope!();
if own_project.check_envelope(&mut envelope).await.is_err() || envelope.is_empty() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move the call to check_envelope into resolve_project? Then you wouldn't have to return both Project and ProjectInfo from that function (though you'd still need the rate_limits).

match self {
Self::Enabled(info) => Some(info),
Self::Disabled | Self::Pending => None,
Self::DummyAllowed | Self::Disabled | Self::Pending => None,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote to remove the .enabled() function entirely. The few places that use it now gloss over the fact that we forgot about proxy mode in those places (as you pointed out in the PR description). So we could replace those calls with explicit match statements and comment on the flawed proxy handling.

Comment on lines +740 to +744
// Since downstream requires a project config, we re-use this dummy config.
//
// This is how Relay historically always handled its proxy mode.
// It would make sense to instead of passing down this dummy, making the project
// config state here optional or similarly typed to the project state.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed unfortunate. Maybe in a follow-up we could have an EnabledProject enum that we pass into ProcessEnvelope:

enum ProjectState {
    Enabled(EnabledProject),
    Disabled,
}

enum EnabledProject { // This goes into the processor
    Loaded(Arc<ProjectInfo>),
    Dummy,
}

That would also help with special-casing proxy mode in the processor, i.e. instead of checking if mode == RelayMode::Proxy, match on the EnabledProject. That would also force authors of processing code to think about proxy mode.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that's a good idea.

That would also help with special-casing proxy mode in the processor [..]

Since we already have 2 separate processor implementations, this wouldn't even be annoying, the proxy processor could ignore it, the non-proxy one would "assert" it's Enabled.

/// This is used by proxy Relay instances which still communicate with the project cache,
/// but never fetch project configs from upstream. In this configuration data must still be
/// forwarded even without a project config.
DummyAllowed,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming suggestion.

Suggested change
DummyAllowed,
Dummy,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants